import { LinkType, LinkStatus, Permissons } from '../api'

// 纯函数

export const sizeNum = (n: number) => {
	if (n >= 1e9)
		return Math.round(n / 1e9) + 'G'
	if (n >= 1e6)
		return Math.round(n / 1e6) + 'M'
	if (n >= 1e3)
		return Math.round(n / 1e3) + 'K'
	return n
}, countColor = (c: number, p: number, t: number) => {
	t = 0.954 ** ((Date.now() - t) / 864e5)
	const s = 2 * Math.atan(6 * Math.log(c / p)) / Math.PI,
		col = s > 0 ? [s, 0, t] : [0, s, t]
	return col.map(x => (x * 255 | 0).toString(16).padStart(2, '0')).join('')
}

/** 统计标签数 */
export const countTag = (s?: string) => countChar(s, ' ') + (s ? 1 : 0)

/** 统计字符数 */
export const countChar = (s: string | undefined, c: string) => {
	let n = 0
	if (s)
		for (const i of s)
			if (i == c)
				n++
	return n
}

/**
 * 转换为十六进制字符串
 */
export const hexString = (arr: Iterable<number>) =>
	[...arr].map((x: number) => x.toString(16).padStart(2, '0')).join('')

export const hexColor = (...col: number[]) =>
	col.map(x => (x * 255 | 0).toString(16).padStart(2, '0')).join('')

/**
 * 渲染值
 * @param key 键名
 * @param val 值
 * @returns 渲染后的值
 */
export function render(key: string, val: any) {
	switch (typeof val) {
		case 'boolean':
			return val ? '是' : '否'
		case 'number':
			if (key == 'perm')
				return permToStr(val)
			if (key.endsWith('_at'))
				return new Date(val).toLocaleString()
			if (key == 'type')
				return LinkType[val] || '未知'
			if (key == 'status')
				return LinkStatus[val] || '未知'
			return val + ''
		case 'object':
			if (val instanceof Uint8Array)
				return hexString(val.length == 33 ? val.subarray(1) : val)
	}
	return val == null ? '' : val
}

/**
 * 将权限转换为字符串
 * @param perm 权限
 * @returns 权限字符串
 */
function permToStr(perm: number) {
	let name = Permissons[perm] || ''
	if (name)
		return name
	for (let i = 0; i < 14; i++)
		if (perm & (1 << i)) {
			if (name) name += ','
			name += Permissons[1 << i]
		}
	return name
}

/**
 * 提交表单
 * @param e 事件
 */
export function submitOnEnter(e: KeyboardEvent) {
	if (e.key == 'Enter') {
		(<HTMLElement>(<HTMLElement>e.target).nextElementSibling)?.click()
	}
}

// a^b -> (-a b|a -b)
export function preprocess(str: string) {
	let r = '', // 结果
		a = '', // 操作数1
		b = '', // 操作数2
		stack = [],
		flush = () => {
			if (b) a = `((${a}) -(${b})|(${b}) -(${a}))`
		},
		lastCh = ' ' // 上一个字符
	for (const ch of str) {
		switch (ch) {
			case '(':
				a += ch
				if ('^-(|) '.includes(lastCh)) {
					stack.push([a, b, r])
					a = b = r = ''
				} else stack.push()
				break
			case ')':
				let x = stack.pop()
				if (x) {
					flush()
					let tmp = a;
					[a, b, r] = x
					a += tmp
				}
				a += ch
				break
			case '|':
				flush()
				b = ''
				r += a + '|'
				a = ''
				break
			case '^':
				flush()
				b = a
				a = ''
				break
			default:
				a += ch
		}
		lastCh = ch
	}
	flush()
	r += a
	for (; ;) {
		a = r.replace(/(?<=^|\||-| |\))\((-?\b[^^\-\s]*?)\)/g, '$1')
		if (a == r) break
		r = a
	}
	// 移除双重减号
	r = r.replace(/--/g, '')
	// 移除多余的括号
	let level = 0
	for (let i = 0; i < r.length; ++i) {
		if (r[i] == '(')
			level++
		else if (r[i] == ')') {
			level--
			if (level == 0) {
				if (i == r.length - 1)
					r = r.substring(1, i)
				break
			}
		}
	}
	// 确保每个')'前有空格
	return r.replace(/\)/g, ' )')
}
